home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / qbsnip.zip / ENVIRON.BAS < prev    next >
BASIC Source File  |  1997-06-19  |  16KB  |  421 lines

  1. '***********************************************************************
  2. '* MODULE Environ
  3. '*
  4. '* EXTERNAL ROUTINE(S)
  5. '*    QB.LIB
  6. '*       SUB InterruptX (IntNum%, RegsX AS RegTypeX, RegsX AS RegTypeX)
  7. '*
  8. '* CREDIT(S)
  9. '*    Douglas Lusher, Fidonet QuickBASIC, 07-11-94
  10. '*
  11. '* MODIFICATIONS:
  12. '*    Tue, 07-20-94 - Generally cleaned up the code.  Modified the
  13. '*    following routines:
  14. '*
  15. '*       FUNCTION MasterEnvInt$
  16. '*          Removed ERROR statement, added ErrCode% parameter and
  17. '*          assigned unique error codes for each error condition.
  18. '*
  19. '*          Changed "Tmp$ = SPACE$(128)" to "Tmp$ = SPACE(256)" to
  20. '*          support 4DOS which allows environment variables > 128 bytes.
  21. '*          Actually, 4DOS allows environment variables somewhat < 256
  22. '*          bytes, but this is good enough. :)
  23. '*
  24. '*       FUNCTION MasterEnvSet%
  25. '*          Changed from SUB to FUNCTION - ErrCode% parameter no longer
  26. '*          needed.
  27. '*
  28. '*       FUNCTION MasterEnvStr$
  29. '*          Removed ERROR statement, added ErrCode% parameter and
  30. '*          assigned unique error codes for each error condition.
  31. '*
  32. '*          Changed "Tmp$ = SPACE$(128)" to "Tmp$ = SPACE(256)" to
  33. '*          support 4DOS which allows environment variables > 128 bytes.
  34. '***********************************************************************
  35. ' additional modifications by Jack Hudgions 02/01/95:
  36. '   changed MasterEnvSet Function as suggested by Mark Northcutt.
  37.  
  38. DEFINT A-Z
  39.  
  40. '$INCLUDE: 'qb.bi'
  41.  
  42. DECLARE FUNCTION MasterEnvFree% ()
  43. DECLARE FUNCTION MasterEnvInt$ (StringNum%, ErrCode%)
  44. DECLARE FUNCTION MasterEnvSeg& ()
  45. DECLARE FUNCTION MasterEnvSet% (Env$)
  46. DECLARE FUNCTION MasterEnvSize% ()
  47. DECLARE FUNCTION MasterEnvStr$ (DefStr$, ErrCode%)
  48. DECLARE SUB ListTable ()
  49.  
  50. 'A demo:
  51. PRINT "Master Environment info:"
  52.  
  53. PRINT "      Size ="; MasterEnvSize%
  54. PRINT "      Used ="; MasterEnvSize% - MasterEnvFree%
  55. PRINT "      Free ="; MasterEnvFree%
  56. PRINT "   Segment = "; HEX$(MasterEnvSeg&)
  57. PRINT
  58. PRINT "   Current environment variables are:"
  59. DO
  60.    StringNum% = StringNum% + 1
  61.    Environment$ = MasterEnvInt$(StringNum%, ErrCode%)
  62.    IF ErrCode% = 0 THEN
  63.       EqualPtr% = INSTR(Environment$, "=")
  64.       EnvName$ = LEFT$(Environment$, EqualPtr% - 1)
  65.       EnvVal$ = MID$(Environment$, EqualPtr% + 1)
  66.  
  67.       PRINT "      "; UCASE$(EnvName$)
  68.       PRINT "         "; LEFT$(EnvVal$, 67);
  69.  
  70.       IF LEN(EnvVal$) > 67 THEN
  71.      PRINT "..."
  72.      PRINT "         ..."; MID$(EnvVal$, 68)
  73.       ELSE
  74.      PRINT
  75.       END IF
  76.    END IF
  77. LOOP UNTIL ErrCode% > 0
  78.  
  79. PRINT : INPUT "   Enter an environment variable to retrieve: ", DefStr$
  80.  
  81. Environment$ = MasterEnvStr$(DefStr$, ErrCode)
  82. SELECT CASE ErrCode%
  83.    CASE 0: PRINT "      "; DefStr$; "="; Environment$
  84.    CASE 2: PRINT "      ERROR - you entered a '=' character!"
  85.    CASE 3: PRINT "      ERROR - you entered a NULL character!"
  86. END SELECT
  87. PRINT
  88. INPUT "   Enter an environment variable name to modify: ", EnvName$
  89.  
  90. IF LEN(EnvName$) THEN
  91.    INPUT "                                Enter new value: ", EnvVal$
  92.    IF LEN(EnvVal$) THEN
  93.       Env$ = EnvName$ + "=" + EnvVal$
  94.       ErrCode% = MasterEnvSet%(Env$)
  95.    END IF
  96. END IF
  97.  
  98. PRINT : PRINT "Type 'SET' at the DOS prompt to see the new values"
  99. END
  100.  
  101. '***********************************************************************
  102. '* FUNCTION MasterEnvFree%
  103. '*
  104. '* PURPOSE
  105. '*    Returns the amount of free space in the master environment.
  106. '*
  107. '* INTERNAL ROUTINE(S)
  108. '*    FUNCTION MasterEnvSeg& ()
  109. '*    FUNCTION MasterEnvSize% ()
  110. '***********************************************************************
  111. FUNCTION MasterEnvFree%
  112.    EnvPtr% = -1                              'Pointer into environment
  113.  
  114.    DEF SEG = MasterEnvSeg&                   'Set segment to Master Env.
  115.    DO
  116.       DO
  117.       EnvPtr% = EnvPtr% + 1                  'Examine next character
  118.       LOOP WHILE PEEK(EnvPtr%)               'Loop until a double NULL
  119.    LOOP WHILE PEEK(EnvPtr% + 1)              '  (terminates the envir.)
  120.    DEF SEG                                   'Restore default segment
  121.  
  122.    'Assign return value
  123.    MasterEnvFree% = MasterEnvSize% - (EnvPtr% + 2)
  124. END FUNCTION
  125.  
  126. '***********************************************************************
  127. '* FUNCTION MasterEnvInt$
  128. '*
  129. '* PURPOSE
  130. '*    Returns an environment string specified by StringNum%.
  131. '*
  132. '*    ErrCode% return values:
  133. '*       1  StringNum% < 1
  134. '*       2  StringNum% > the number of environment variables
  135. '*
  136. '* INTERNAL ROUTINE(S)
  137. '*    FUNCTION MasterEnvSeg& ()
  138. '***********************************************************************
  139. FUNCTION MasterEnvInt$ (StringNum%, ErrCode%)
  140.    MasterEnvInt$ = ""                        'Initialize some variables
  141.    EnvPtr% = -1                              'Pointer into environment
  142.    Count% = 0                                '# of environ. vars. found
  143.    ErrCode% = 0                              'Return value
  144.  
  145.    IF StringNum% < 1 THEN
  146.       ErrCode% = 1                           'Must be >= 1
  147.       EXIT FUNCTION                          'Bail out
  148.    END IF
  149.  
  150.    DEF SEG = MasterEnvSeg&                   'Set segment to Master Env.
  151.  
  152.    DO
  153.       IF PEEK(EnvPtr% + 1) = 0 THEN          'StringNum% > # of
  154.      ErrCode% = 2                            '  environment variables
  155.      EXIT DO                                 'Bail out
  156.       END IF
  157.  
  158.       Count% = Count + 1                     'Next env. variable
  159.       IF Count% < StringNum% THEN            '
  160.      DO                                      'Find end of current var.
  161.         EnvPtr% = EnvPtr% + 1                'Examine next character
  162.         IF PEEK(EnvPtr%) = 0 THEN            'NULL (end) found
  163.            EXIT DO                           '  exit loop
  164.         END IF
  165.      LOOP
  166.       ELSE                                   'Found specified env. var.
  167.      Tmp$ = SPACE$(256)                      'This is where we'll hold the
  168.                                              '  result
  169.      StrPtr% = 0
  170.      DO                                      'Find end of env. variable
  171.         EnvPtr% = EnvPtr% + 1                'Examine next character
  172.         EnvCh% = PEEK(EnvPtr%)
  173.         IF EnvCh% = 0 THEN                   'Loop until
  174.            EXIT DO                           '  NULL is found
  175.         END IF
  176.  
  177.         StrPtr% = StrPtr% + 1                'Insert character
  178.         MID$(Tmp$, StrPtr%, 1) = CHR$(EnvCh%)
  179.      LOOP
  180.  
  181.      MasterEnvInt$ = LEFT$(Tmp$, StrPtr%)    'Assign return value
  182.      EXIT DO
  183.       END IF
  184.    LOOP
  185.  
  186.    DEF SEG                                   'Restore default segment
  187. END FUNCTION
  188.  
  189. '***********************************************************************
  190. '* FUNCTION MasterEnvSeg&
  191. '*
  192. '* PURPOSE
  193. '*    Uses (an apparently undocumented) feature of DOS ISR 21H, Function
  194. '*    35H (Get Interrupt Vector) to return the segment of the Master
  195. '*    Environment.
  196. '*
  197. '* EXTERNAL ROUTINE(S)
  198. '*    SUB InterruptX (IntNum%, InReg AS RegTypeX, OutReg AS RegTypeX)
  199. '***********************************************************************
  200. FUNCTION MasterEnvSeg& STATIC
  201.    DIM RegsX AS RegTypeX
  202.  
  203.    RegsX.ax = &H352E
  204.    INTERRUPTX &H21, RegsX, RegsX
  205.  
  206.    DEF SEG = RegsX.es
  207.    MasterEnvSeg& = PEEK(&H2C) + PEEK(&H2D) * 256&
  208.    DEF SEG                                   'Restore default segment
  209. END FUNCTION
  210.  
  211. '***********************************************************************
  212. '* FUNCTION MasterEnvSet%
  213. '*
  214. '* PURPOSE
  215. '*    Sets the specified environment string (Env$) in the master
  216. '*    environment.  Returns 1 if Env$ is empty, if Env$ contains a NULL,
  217. '*    or if Env$ does not contain a "=".  Returns 2 if the result
  218. '*    (after adding/changing Env$) is too long to fit into the maximum
  219. '*    Master Environment size.
  220. '*
  221. '* INTERNAL ROUTINE(S)
  222. '*    FUNCTION MasterEnvSeg& ()
  223. '*    FUNCTION MasterEnvSize% ()
  224. '***********************************************************************
  225. FUNCTION MasterEnvSet% (Env$)
  226.    null$ = CHR$(0)
  227.  
  228.    IF LEN(Env$) = 0 THEN                     'Is it set?
  229.       MasterEnvSet% = 1                      '  no, exit
  230.       EXIT FUNCTION                          '  with error
  231.    END IF
  232.  
  233.    IF INSTR(Env$, null$) THEN                'Does it have a null?
  234.       MasterEnvSet% = 2                      '  Yes, exit
  235.       EXIT FUNCTION                          '  with error.
  236.    END IF
  237.  
  238.    EqualPtr% = INSTR(Env$, "=")              'Find the "="
  239.    IF EqualPtr% <= 1 THEN                    'Was it found?
  240.       MasterEnvSet% = 3                      '  No, exit
  241.       EXIT FUNCTION                          '  with error
  242.    END IF
  243.  
  244.    EVar$ = UCASE$(LEFT$(Env$, EqualPtr%))    'Grab the environment name
  245.    EnvVal$ = MID$(Env$, EqualPtr% + 1)       'Grab the environment value
  246.  
  247.    EnvSize% = MasterEnvSize%
  248.    EnvSeg& = MasterEnvSeg&
  249.  
  250.    Tmp$ = SPACE$(EnvSize%)
  251.    DEF SEG = EnvSeg&
  252.    FOR EqualPtr% = 1 TO LEN(Tmp$)            'Copy the env. to a string
  253.       MID$(Tmp$, EqualPtr%, 1) = CHR$(PEEK(EqualPtr% - 1))
  254.    NEXT
  255.    DEF SEG                                   'Restore default segment
  256.  
  257.    'Chop it off at the end of the last environment string
  258.    Tmp$ = LEFT$(Tmp$, INSTR(Tmp$, null$ + null$))
  259.  
  260.    IF LEN(Tmp$) = 1 THEN                     'If the environment happens
  261.       Tmp$ = ""                              '  to be empty
  262.    END IF
  263.  
  264. '   EnvVarPtr% = INSTR(Tmp$, EVar$)           'Is Env$ is in the environ?
  265. ' Mark's modification begin.
  266.    EnvVarPtr% = INSTR(Tmp$, null$ + EVar$) + 1'Is Env$ is in the environ?
  267.    IF EnvVarPtr% = 0 THEN
  268.        EnvVarPtr% = INSTR(Tmp$, EVar$)        'if null+var is not there,
  269.                                               ' maybe it's (rest cut off)
  270.        IF EnvVarPtr% > 1 THEN EnvVarPtr% = 0  'if not #1 then found a
  271.                                               ' substr later
  272.    END IF
  273. ' Mark's modification end.
  274.  
  275.    IF EnvVarPtr% THEN
  276.       'Find the beginning of the next environment variable
  277.       NextPtr% = INSTR(EnvVarPtr%, Tmp$, null$) + 1
  278.  
  279.       IF NextPtr% > LEN(Tmp$) THEN           'EVar$ is the last var. in
  280.      Tmp$ = LEFT$(Tmp$, EnvVarPtr% - 1)      '  the environ, so keep
  281.       ELSE                                   '  everything before it.
  282.      'EVar$ isn't the last variable so move everything after it up
  283.      Tmp$ = LEFT$(Tmp$, EnvVarPtr% - 1) + MID$(Tmp$, NextPtr%)
  284.       END IF
  285.    END IF
  286.  
  287.    IF LEN(EnvVal$) THEN                      'Are we setting it,
  288.       'Add Env$ to the end of the envir. and terminate with two nulls
  289.       Tmp$ = Tmp$ + EVar$ + EnvVal$ + null$ + null$
  290.       IF LEN(Tmp$) > EnvSize% THEN           'Is the result too long?
  291.      MasterEnvSet% = 2                       'Yes, exit with
  292.      EXIT FUNCTION                           '  error
  293.       END IF
  294.    ELSE                                      'Or removing it?
  295.       'If EnvVal$ is empty then all we wanted to do
  296.       '  was remove the variable from the environment
  297.       Tmp$ = Tmp$ + null$
  298.  
  299.       IF LEN(Tmp$) = 1 THEN                  'If this happened to be the
  300.      Tmp$ = Tmp$ + null$                     '  last environ. var., an
  301.       END IF                                 '  extra null is needed to
  302.    END IF                                    '  terminate.
  303.  
  304.    DEF SEG = EnvSeg&
  305.    FOR Ptr% = 1 TO LEN(Tmp$)                 'Copy the string back into
  306.       POKE Ptr% - 1, ASC(MID$(Tmp$, Ptr%, 1))'  the environment
  307.    NEXT
  308.    DEF SEG                                   'Restore default segment
  309.  
  310.    MasterEnvSet% = 0                         'Everything OK
  311. END FUNCTION
  312.  
  313. '***********************************************************************
  314. '* FUNCTION MasterEnvSize%
  315. '*
  316. '* PURPOSE
  317. '*    Returns the size of the master environment in bytes.
  318. '***********************************************************************
  319. FUNCTION MasterEnvSize%
  320.    DEF SEG = MasterEnvSeg& - 1               'Set segment to Master Env.
  321.    MasterEnvSize% = (PEEK(3) + PEEK(4) * 256) * 16
  322.    DEF SEG                                   'Restore default segment
  323. END FUNCTION
  324.  
  325. '***********************************************************************
  326. '* FUNCTION MasterEnvStr$
  327. '*
  328. '* PURPOSE
  329. '*    Returns an environment string specified by DefStr$.
  330. '*
  331. '*    ErrCode% return values:
  332. '*       0     Success
  333. '*       1     DefStr$ is empty
  334. '*       2     DefStr$ contains a "="
  335. '*       3     DefStr$ contains an embedded NULL
  336. '*
  337. '* INTERNAL ROUTINE(S)
  338. '*    FUNCTION MasterEnvSeg& ()
  339. '***********************************************************************
  340. FUNCTION MasterEnvStr$ (DefStr$, ErrCode%)
  341.    IF LEN(DefStr$) = 0 THEN
  342.       ErrCode% = 1                           'String is empty
  343.       EXIT FUNCTION                          'Bail out
  344.    END IF
  345.  
  346.    IF INSTR(DefStr$, "=") THEN
  347.       ErrCode% = 2                           'Invalid environment string
  348.       EXIT FUNCTION                          '  (contains a "="), bail
  349.    END IF                                    '  out.
  350.  
  351.    IF INSTR(DefStr$, CHR$(0)) THEN
  352.       ErrCode% = 3                           'Invalid environment string
  353.       EXIT FUNCTION                          '  (contains a NULL), bail
  354.    END IF                                    '  out.
  355.  
  356.    Tmp$ = UCASE$(DefStr$) + "="
  357.    DefLen% = LEN(Tmp$)
  358.    REDIM DefCh%(1 TO DefLen%)                'Fill DefCh%()
  359.    FOR StrPtr% = 1 TO DefLen%                '  with given environ. var.
  360.       DefCh%(StrPtr%) = ASC(MID$(Tmp$, StrPtr%, 1))
  361.    NEXT
  362.  
  363.    MasterEnvStr$ = ""                        'Initialize some variables
  364.    Found% = 0
  365.    EnvPtr% = -1
  366.  
  367.    DEF SEG = MasterEnvSeg&                   'Set segment to Master Env.
  368.  
  369.    DO
  370.       IF PEEK(EnvPtr% + 1) = 0 THEN          'Found terminating NULL
  371.         EXIT DO                              'Bail out
  372.       END IF
  373.  
  374.       StrPtr% = 0
  375.       DO                                     'Find match for DefStr$
  376.      StrPtr% = StrPtr% + 1                   '  (DefCh%()) in environ.
  377.      IF StrPtr% > DefLen% THEN               'Longer than our env. var.
  378.         GOSUB SkipString                     'It isn't this one,
  379.         EXIT DO                              '  skip it
  380.      END IF
  381.  
  382.      EnvPtr% = EnvPtr% + 1               'Pointer into environment
  383.      EnvCh% = PEEK(EnvPtr%)              'Get next byte in environ.
  384.      IF EnvCh% = DefCh%(StrPtr%) THEN    'Do the chars. match?
  385.         IF StrPtr% = DefLen% THEN        'Is the length the same?
  386.            Found% = -1                   'Found it!
  387.            EXIT DO                       'Bail out
  388.         END IF
  389.      ELSE
  390.         GOSUB SkipString                 'It isn't this one,
  391.         EXIT DO                          '  skip it
  392.      END IF
  393.       LOOP
  394.  
  395.       IF Found% THEN                         'If we found it,
  396.      Tmp$ = SPACE$(256)                      'New copy will go here
  397.      StrPtr% = 0
  398.      DO UNTIL EnvCh% = 0                 'Grab the value
  399.         EnvPtr% = EnvPtr% + 1            '  and insert
  400.         EnvCh% = PEEK(EnvPtr%)           '  it in
  401.         StrPtr% = StrPtr% + 1            '  Tmp$
  402.         MID$(Tmp$, StrPtr%, 1) = CHR$(EnvCh%)
  403.      LOOP
  404.  
  405.      MasterEnvStr$ = LEFT$(Tmp$, StrPtr%)
  406.      EXIT DO
  407.       END IF
  408.    LOOP
  409.    DEF SEG                                   'Restore default segment
  410.    ErrCode% = 0                              'Success
  411.    EXIT FUNCTION                             'All done
  412.  
  413. SkipString:                                  'Skip current environ. var.
  414.    DO UNTIL EnvCh% = 0                       'Look for terminating NULL
  415.       EnvPtr% = EnvPtr% + 1
  416.       EnvCh% = PEEK(EnvPtr%)
  417.    LOOP
  418. RETURN
  419. END FUNCTION
  420.  
  421.